import { ESObjectsManager, SceneTreeItem } from 'earthsdk3';
import { getNoonTimestamp } from "./utils"

import { Event, react } from "earthsdk3";
import * as Cesium from "cesium";
import { BaseSceneConfig } from './baseSceneConfig';
import { SwitchEngine } from './switchEngine';
import { CimrtsManager } from './cimrtsManager';
import { ModelserManager } from './modelserManager';
import { ESForestManager } from './eSForestManager';
import { Modelser2Manager } from './modelser2Manager';
import { ESUeViewer } from 'earthsdk3-ue';
import { ElMessage } from 'element-plus';
import { TerrainRtsManager } from './terrainrtsManager';



export class MyProjectManager extends ESObjectsManager {

    //当前激活的Viewer
    private _typeName = this.dv(react<string>("ESCesiumViewer"));
    get typeName() { return this._typeName.value; }
    get typeNameChanged() { return this._typeName.changed; }
    set typeName(value: string) { this._typeName.value = value; }

    // 深度检测
    private _depthTestAgainstTerrainRef = this.dv(react<boolean>(true));
    get depthTestAgainstTerrainRef() { return this._depthTestAgainstTerrainRef.value; }
    get depthTestAgainstTerrainRefChanged() { return this._depthTestAgainstTerrainRef.changed; }
    set depthTestAgainstTerrainRef(value: boolean) { this._depthTestAgainstTerrainRef.value = value; }

    // 地形检测
    private _showCesiumInspector = this.dv(react<boolean>(false));
    get showCesiumInspector() { return this._showCesiumInspector.value; }
    get showCesiumInspectorChanged() { return this._showCesiumInspector.changed; }
    set showCesiumInspector(value: boolean) { this._showCesiumInspector.value = value; }

    //属性对象
    private _propSceneTree = this.dv(react<any>(undefined));
    get propSceneTree() { return this._propSceneTree.value; }
    get propSceneTreeChanged() { return this._propSceneTree.changed; }
    set propSceneTree(value: any) { this._propSceneTree.value = value; }


    //modelser属性对象
    private _modelserPropSceneTree = this.dv(react<any>(undefined));
    get modelserPropSceneTree() { return this._modelserPropSceneTree.value; }
    get modelserPropSceneTreeChanged() { return this._modelserPropSceneTree.changed; }
    set modelserPropSceneTree(value: any) { this._modelserPropSceneTree.value = value; }

    //modelser2属性对象
    private _modelser2PropSceneTree = this.dv(react<any>(undefined));
    get modelser2PropSceneTree() { return this._modelser2PropSceneTree.value; }
    get modelser2PropSceneTreeChanged() { return this._modelser2PropSceneTree.changed; }
    set modelser2PropSceneTree(value: any) { this._modelser2PropSceneTree.value = value; }

    //terrainRts属性对象
    private _terrainRtsPropSceneTree = this.dv(react<any>(undefined));
    get terrainRtsPropSceneTree() { return this._terrainRtsPropSceneTree.value; }
    get terrainRtsPropSceneTreeChanged() { return this._terrainRtsPropSceneTree.changed; }
    set terrainRtsPropSceneTree(value: any) { this._terrainRtsPropSceneTree.value = value; }

    //forest属性对象
    private _forestPropSceneTree = this.dv(react<any>(undefined));
    get forestPropSceneTree() { return this._forestPropSceneTree.value; }
    get forestPropSceneTreeChanged() { return this._forestPropSceneTree.changed; }
    set forestPropSceneTree(value: any) { this._forestPropSceneTree.value = value; }

    // 显示地球
    private _globeShowRef = this.dv(react<boolean>(true));
    get globeShowRef() { return this._globeShowRef.value; }
    get globeShowRefChanged() { return this._globeShowRef.changed; }
    set globeShowRef(value: boolean) { this._globeShowRef.value = value; }

    // 时间线
    private _currentTime = this.dv(react<number>(0));
    get currentTime() { return this._currentTime.value; }
    get currentTimeChanged() { return this._currentTime.changed; }
    set currentTime(value: number) { this._currentTime.value = value; }

    // fov
    private _fov = this.dv(react<number>(60));
    get fov() { return this._fov.value; }
    get fovChanged() { return this._fov.changed; }
    set fov(value: number) { this._fov.value = value; }

    // 地球表面颜色
    private _globeBaseColor = this.dv(react<[number, number, number, number]>([1, 1, 1, 1]));
    get globeBaseColor() { return this._globeBaseColor.value; }
    get globeBaseColorChanged() { return this._globeBaseColor.changed; }
    set globeBaseColor(value: [number, number, number, number]) { this._globeBaseColor.value = value; }

    private _ueIsShow = this.dv(react<boolean>(false));//视口
    get ueIsShow() { return this._ueIsShow.value; }
    set ueIsShow(value: boolean) { this._ueIsShow.value = value; }
    get ueIsShowChanged() { return this._ueIsShow.changed; }

    // 地图模式
    private _mapMode = this.dv(react<string>("Map"));
    get mapMode() { return this._mapMode.value; }
    set mapMode(value: string) { this._mapMode.value = value; }
    get mapModeChanged() { return this._mapMode.changed; }

    // 批量旋转事件
    private _batchRotateEvent = this.dv(new Event<[string]>());
    get batchRotateEvent() { return this._batchRotateEvent; }

    // 批量位置事件
    private _batchPositionEvent = this.dv(new Event<[string]>());
    get batchPositionEvent() { return this._batchPositionEvent; }

    // cimrts场景树
    get cimrtsSceneTreeWrapper() {
        if (this.getSceneTree("cimrtsSceneTreeWrapper")) {
            return this.getSceneTree("cimrtsSceneTreeWrapper")
        } else {
            this.createSceneTree("cimrtsSceneTreeWrapper", 28)
            return this.getSceneTree("cimrtsSceneTreeWrapper")
        }
    }

    // modelser场景树
    get modelserSceneTreeWrapper() {
        if (this.getSceneTree("modelserSceneTreeWrapper")) {
            return this.getSceneTree("modelserSceneTreeWrapper")
        } else {
            this.createSceneTree("modelserSceneTreeWrapper", 28)
            return this.getSceneTree("modelserSceneTreeWrapper")
        }
    }

    // modelser2场景树
    get modelser2SceneTreeWrapper() {
        if (this.getSceneTree("modelser2SceneTreeWrapper")) {
            return this.getSceneTree("modelser2SceneTreeWrapper")
        } else {
            this.createSceneTree("modelser2SceneTreeWrapper", 28)
            return this.getSceneTree("modelser2SceneTreeWrapper")
        }
    }

    // forest场景树
    get forestSceneTreeWrapper() {
        if (this.getSceneTree("forestSceneTreeWrapper")) {
            return this.getSceneTree("forestSceneTreeWrapper")
        } else {
            this.createSceneTree("forestSceneTreeWrapper", 28)
            return this.getSceneTree("forestSceneTreeWrapper")
        }
    }

    // terrainRts场景树
    get terrainRtsSceneTreeWrapper() {
        if (this.getSceneTree("terrainRtsSceneTreeWrapper")) {
            return this.getSceneTree("terrainRtsSceneTreeWrapper")
        } else {
            this.createSceneTree("terrainRtsSceneTreeWrapper", 28)
            return this.getSceneTree("terrainRtsSceneTreeWrapper")
        }
    }

    // 基础场景
    private _baseSceneConfig: undefined | BaseSceneConfig = undefined
    get baseSceneConfig() { return this._baseSceneConfig; }
    set baseSceneConfig(value: BaseSceneConfig | undefined) { this._baseSceneConfig = value }

    // Cesium UE 切换
    private _switchEngine = this.dv(new SwitchEngine(this));
    get switchEngine() { return this._switchEngine; }

    // cimrtsManager
    private _cimrtsManager = this.dv(new CimrtsManager(this));
    get cimrtsManager() { return this._cimrtsManager; }

    // modelser
    private _modelserManager = this.dv(new ModelserManager(this));
    get modelserManager() { return this._modelserManager; }

    // modelser2
    private _modelser2Manager = this.dv(new Modelser2Manager(this));
    get modelser2Manager() { return this._modelser2Manager; }

    // eSForest
    private _eSForestManager = this.dv(new ESForestManager(this));
    get eSForestManager() { return this._eSForestManager; }

    // terrainRts
    private _terrainrtsManager = this.dv(new TerrainRtsManager(this));
    get terrainrtsManager() { return this._terrainrtsManager; }

    // 设置场景对象名称（根据传入的名称）
    setSceneObjName(json: any, name: string) {
        let result: any = [1]
        const fun = (json: any, num: number, name: string) => {
            json?.forEach((item: any) => {
                // 说明是场景对象
                if (item.sceneObj) {
                    result = item.name.includes(name) ? [...result, 1] : [...result]
                }

                // 文件夹里面是否还有文件夹
                if (item.children && item.children.length > 0) {
                    fun(item.children, num, name)
                }
            })
        }
        fun(json, result, name)
        return result.length
    }

    // 设置文件夹名字
    setGroupName(json: any, name: string) {
        let result: any = [1]
        const fun = (json: any, num: number, name: string) => {
            json?.forEach((item: any) => {
                // 说明是文件夹
                if (!item.sceneObj) {
                    result = item.name.includes(name) ? [...result, 1] : [...result]
                }

                // 文件夹里面是否还有文件夹
                if (item.children && item.children.length > 0) {
                    fun(item.children, num, name)
                }
            })
        }
        fun(json, result, name)
        return result.length
    }

    // 场景树上上创建一个treeItem
    createdTreeItem(sceneTreeWrapper: any) {
        const lastSelectedItem = sceneTreeWrapper?.lastSelectedItem
        // @ts-ignore
        const treeItem = sceneTreeWrapper.addNewTreeItem(lastSelectedItem, 'InnerOrAfter')
        return treeItem as SceneTreeItem
    }

    // 在文件夹里面创建场景对象
    createdTreeItemInnerGroup(sceneTreeWrapper: any, group: any) {
        // @ts-ignore
        const treeItem = sceneTreeWrapper.addNewTreeItem(group, 'InnerOrAfter')
        return treeItem as SceneTreeItem
    }

    // 设置场景树json
    setSceneTreeJson(sceneTreeWrapper: any, json: any) {
        sceneTreeWrapper.setJson({
            "root": {
                "children": json
            }
        })
    }

    // 全局缓存
    overallCache() {
        // @ts-ignore
        const cacheEntries = Object.entries(Cesium.ResourceCache.cacheEntries)
        if (!cacheEntries.length) return 0;
        const newArr = cacheEntries.filter((e: any) => e[0].includes("texture"))

        const sizeInBytes = newArr.reduce((acc, cur) => {
            // @ts-ignore
            if (!cur[1].resourceLoader._texture) return 0;
            // @ts-ignore
            return acc + cur[1].resourceLoader._texture._sizeInBytes
        }, 0)
        return sizeInBytes
    }

    constructor() {
        super();
        {
            const updata = () => {
                console.log("视口切换");

                if (!this.activeViewer) return;
                // this.activeViewer.ionAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzYzBlMDhlMC1kYTE3LTQ1ZDgtYmM4OC1lZjhmODZlZWM5NTYiLCJpZCI6MTM2OTk3LCJpYXQiOjE3NTAyMjU3MTh9.l5CZAzH6Jw_DtA1tWJKg2EGFgXALGYxzhzn3dywlfq8"
                this.baseSceneConfig = new BaseSceneConfig(this)
                // @ts-ignore
                this.activeViewer.depthTestAgainstTerrain = this.depthTestAgainstTerrainRef
            }
            this.dispose(this.activeViewerChanged.disposableOnce(updata))
        }
        {
            const updata = () => {
                if (!this.activeViewer) return;
                this.activeViewer.changeToMap()
                this.mapMode = "Map"
                if (this.activeViewer instanceof ESUeViewer) {
                    this.ueIsShow = true
                } else {
                    this.ueIsShow = false
                }
                this.typeName = this.activeViewer.typeName;
                this.activeViewer.currentTime = getNoonTimestamp()
                if (this.activeViewer.typeName == "ESCesiumViewer") {
                    // @ts-ignore
                    this.activeViewer.editingHeightOffset = 0;
                    // @ts-ignore
                    this.dispose(this.activeViewer.viewerChanged.disposableOn(() => {
                        // @ts-ignore
                        this.activeViewer.extensions.cursorPositionInfo.enabled = true
                    }))

                }
            }
            this.dispose(this.activeViewerChanged.don(updata))
        }

        // 深度检测
        // {
        //     const updata = () => {
        //         if (!this.activeViewer) return;
        //         if ((this.activeViewer.typeName == "ESCesiumViewer")) {
        //             // @ts-ignore
        //             this.activeViewer.depthTestAgainstTerrain = this.depthTestAgainstTerrainRef
        //         } else {
        //             const terrainLists = this.baseSceneConfig?.sceneTreeLists.filter((item: any) => item.type == "terrain")
        //             terrainLists.forEach((item: any) => {
        //                 item._sceneObject.renderMode = this.depthTestAgainstTerrainRef ? "default" : "disableDepthTest"
        //             })
        //         }


        //     }
        //     this.dispose(this.depthTestAgainstTerrainRefChanged.don(updata))
        // }
        {
            const updata = () => {
                if (!this.activeViewer) return;
                // @ts-ignore
                this.activeViewer.depthTestAgainstTerrain = this.depthTestAgainstTerrainRef
            }
            this.dispose(this.depthTestAgainstTerrainRefChanged.don(updata))
        }

        // 显示地球
        {
            const updata = () => {
                if (!this.activeViewer) return;
                // @ts-ignore
                this.activeViewer.globeShow = this.globeShowRef

            }
            this.dispose(this.globeShowRefChanged.don(updata))
        }

        // 地形调试
        {
            const updata = () => {
                if (!this.activeViewer) return;
                // @ts-ignore
                this.activeViewer.showCesiumInspector = this.showCesiumInspector

            }
            this.dispose(this.showCesiumInspectorChanged.don(updata))
        }

        // 时间线
        {
            const updata = () => {
                if (!this.activeViewer) return;
                // @ts-ignore
                this.activeViewer.currentTime = this.currentTime

            }
            this.dispose(this.currentTimeChanged.don(updata))
        }

        // fov
        {
            const updata = () => {
                if (!this.activeViewer) return;
                // @ts-ignore
                this.activeViewer.fov = this.fov

            }
            this.dispose(this.fovChanged.don(updata))
        }
        // 地球表面颜色
        {
            const updata = () => {

                if (!this.activeViewer) return;
                if (!(this.activeViewer.typeName == "ESCesiumViewer")) return;
                if (!this.activeViewer) return;
                // @ts-ignore
                if (!this.activeViewer.viewer) return;
                const c = this.globeBaseColor
                // @ts-ignore
                this.activeViewer.viewer.scene.globe.baseColor = new Cesium.Color(c[0], c[1], c[2], c[3])
            }
            this.dispose(this.globeBaseColorChanged.don(updata))
        }

    }
}



